package com.accounting.client.frontend.customer;

import java.util.ArrayList;
import java.util.List;

import com.accounting.client.frontend.customer.dialog.AddCustomerHandler;
import com.accounting.client.frontend.customer.dialog.CustomerPurchaseListHandler;
import com.accounting.client.frontend.customer.dialog.UpdateCustomerHandler;
import com.accounting.client.remote.Services;
import com.accounting.client.remote.enumeration.Sex;
import com.accounting.client.remote.obj.Customer;
import com.accounting.client.resource.BoxResources;
import com.accounting.client.session.ErrorHandler;
import com.accounting.client.session.SessionManager;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.Widget;

import corelib.client.Util;
import corelib.client.date.DateFormats;
import corelib.client.delegate.Action;
import corelib.client.delegate.DataCallback;
import corelib.client.resource.CommonResources;
import corelib.client.schedule.DeferredTask;
import corelib.client.search.JSONSearchResult;
import corelib.client.search.PagingRequest;
import corelib.client.search.PagingResult;
import corelib.client.ui.SimpleModal;
import corelib.client.ui.widget.SimpleDataModel;
import corelib.client.ui.widget.WidgetListener;
import corelib.client.ui.widget.dialog.SimpleDialog;
import corelib.client.ui.widget.dialog.SimpleLargeDialog;
import corelib.client.ui.widget.form.SimpleLabel;
import corelib.client.ui.widget.grid.SimpleDataGrid;
import corelib.client.ui.widget.grid.SimpleDataGridHandler;
import corelib.client.ui.widget.grid.cell.CellRenderer;
import corelib.client.ui.widget.grid.cell.CheckBoxCellRenderer;
import corelib.client.ui.widget.grid.column.ColumnConfig;
import corelib.client.ui.widget.grid.column.ColumnConfigs;
import corelib.client.ui.widget.messagebox.SimpleMessageBox;
import corelib.client.ui.widget.page.PageBase;
import corelib.client.ui.widget.panel.SimpleLayoutPanel;
import corelib.client.ui.widget.toolbar.SimpleRibbon;
import corelib.client.ui.widget.toolbar.SimpleRibbonButton;
import corelib.client.ui.widget.toolbar.SimpleRibbonButton.ButtonSize;

public class CustomerManager extends PageBase<Widget> {
	
	private int currentOffset = 0;
	private int currentNumOfRecordsPerPage = 0;
	private final static int MaxRecordsPerPage = CustomerSearchPanel.MaxRecordsPerPage;
	
	// Custom Search Panel for customer 
	private CustomerSearchPanel searchPanel;
	
	// Customer table display
	private CustomerTableHandler customerTableHandler;
	private SimpleDataGrid<Customer> customerTable;
	
	// Customer tool bar control
	private SimpleRibbon toolBar;
	private SimpleRibbonButton deleteBtn;
	private SimpleRibbonButton updateBtn;
	private SimpleRibbonButton previousBtn;
	private SimpleRibbonButton nextBtn;
	private SimpleRibbonButton purchaseListBtn;
	
	public CustomerManager(){
		setPageName("客户信息管理");
		setPageIcon(BoxResources.INSTANCE.customer24());
	}
	
	@Override
	protected Widget createWidget() {
		searchPanel = new CustomerSearchPanel(this, new DataCallback<JSONSearchResult<Customer>>(){
			@Override
			public void onCompleted(JSONSearchResult<Customer> data) {
				currentOffset = data.getOffset();
				currentNumOfRecordsPerPage = data.getData().size();
				customerTableHandler.setObjects(data.getData());
				deleteBtn.setEnabled(false);
				updateBtn.setEnabled(false);
				purchaseListBtn.setEnabled(false);
				previousBtn.setEnabled(currentOffset > 0);
				nextBtn.setEnabled(currentNumOfRecordsPerPage + currentOffset <  data.getTotal());
			}
		});
		
		toolBar = createToolBar();
		customerTable = createTable();
		SimpleLayoutPanel panel =  new SimpleLayoutPanel();
		panel.add(toolBar);
		panel.add(customerTable);
		panel.add(searchPanel.asWidget());
		panel.setWidgetTopHeight(toolBar, 0, Unit.PX, 80, Unit.PX);
		panel.setWidgetTopBottom(customerTable, 80, Unit.PX, 0, Unit.PX);
		return panel;
	}
	
	public SimpleDataGrid<Customer> getCustomerTable() {
		return this.customerTable;
	}

	public Customer getSelectedCustomer(){
		return this.customerTable.getSelectedObject();
	}
	
	@Override
	protected void afterCreateWidget(Widget widgetCreated) {
		super.afterCreateWidget(widgetCreated);
		new DeferredTask().run(new ScheduledCommand(){
			@Override
			public void execute() {
				refresh();
			}
		}, 500);
	}

	protected SimpleRibbon createToolBar() {
		SimpleRibbon toolbar = new SimpleRibbon();
		toolbar.addPushButton(new SimpleRibbonButton(
			"增加新客户", 
			BoxResources.INSTANCE.addUser32(),
			ButtonSize.Medium,
			new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					SimpleDialog.show(new AddCustomerHandler(new Action(){
						@Override
						public void run() {
							refresh();
						}
					}));
				}
			}
		));
		toolbar.addPushButton(deleteBtn = new SimpleRibbonButton(
				"删除客户",
				BoxResources.INSTANCE.deleteUser32(),
				ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						Customer info = customerTable.getSelectedObject();
						if (info != null){
							SimpleMessageBox.confirm("删除", "确定要删除这个客户吗?",
								new DataCallback<Boolean>(){
									@Override
									public void onCompleted(Boolean data) {
										if (data == Boolean.TRUE){
											delete();
										}
									}
								}
							);
						}
					}
				}
		));
		toolbar.addPushButton(updateBtn = new SimpleRibbonButton(
				"更新客户信息",
				BoxResources.INSTANCE.updateUser32(),
				ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						Customer info = customerTable.getSelectedObject();
						if (info != null){
							SimpleDialog.show(new UpdateCustomerHandler(info, new Action(){
								@Override
								public void run() {
									refresh();
								}
							}));
						}
					}
				}
		));
		/*toolbar.addPushButton(new SimpleRibbonButton(
				"上传身份证", 
				BoxResources.INSTANCE.upload_id_32(),
				ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						new SimpleUploadDialog()
							.withUrl("http://localhost:4843/IdentityUpload.aspx")
							.withLabel("上传身份证")
							.withParameter("passport", SessionManager.getPassport())
							.show();
					}
				}
		));*/
		toolbar.addPushButton(purchaseListBtn = new SimpleRibbonButton(
				"发送购买清单",
				BoxResources.INSTANCE.sendEmail32(),
				ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						Customer info = customerTable.getSelectedObject();
						if (info != null){
							SimpleLargeDialog.show(new CustomerPurchaseListHandler(info));
						}
					}
				}
		));
		toolbar.addSeparator(ButtonSize.Medium);
		toolbar.addPushButton(new SimpleRibbonButton("刷新",CommonResources.INSTANCE.refresh32(),ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						refresh();
					}
				}
		));
		toolbar.addSeparator(ButtonSize.Medium);
		toolbar.addPushButton(previousBtn = new SimpleRibbonButton("前页",CommonResources.INSTANCE.prev32(),ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						load(Math.max(currentOffset - MaxRecordsPerPage, 0));
					}
				}
	    ));
		toolbar.addPushButton(nextBtn = new SimpleRibbonButton("后页",CommonResources.INSTANCE.next32(),ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						load(Math.max(currentOffset + MaxRecordsPerPage, 0));
					}
				}
		));
		deleteBtn.setEnabled(false);
		updateBtn.setEnabled(false);
		nextBtn.setEnabled(false);
		previousBtn.setEnabled(false);
		purchaseListBtn.setEnabled(false);
		return toolbar;
	}
	
	public void refresh() {
		load(currentOffset);
	}
	
	private void load(int offset){
		String passport = SessionManager.getPassport();
		PagingRequest request = new PagingRequest();
		request.setOffset(offset);
		request.setLimit(MaxRecordsPerPage);
		
		SimpleModal.show("努力加载中...");
		Services.CustomerService.ListCustomers(passport, request,
		    new AsyncCallback<PagingResult<Customer>>(){
				@Override
				public void onFailure(Throwable caught) {
					SimpleModal.hide();;
					ErrorHandler.handleServiceError(caught);
				}
				
				@Override
				public void onSuccess(PagingResult<Customer> result) {
					SimpleModal.hide();
					currentOffset = result.getOffset();
				    currentNumOfRecordsPerPage = result.getData().size();
					customerTableHandler.setObjects(result.getData());
					
					purchaseListBtn.setEnabled(false);
					deleteBtn.setEnabled(false);
					updateBtn.setEnabled(false);
					nextBtn.setEnabled(currentNumOfRecordsPerPage + currentOffset < result.getTotal());
					previousBtn.setEnabled(currentOffset > 0);
				}
			}
	    );
	}
	
	private void delete() {
		String passport = SessionManager.getPassport();
		Customer info = customerTable.getSelectedObject();
		Services.CustomerService.RemoveCustomer(passport,info.getId(),
			new AsyncCallback<Boolean>(){
				@Override
				public void onFailure(Throwable caught) {
					ErrorHandler.handleServiceError(caught);
				}
				
				@Override
				public void onSuccess(Boolean result) {
					if (result == Boolean.TRUE){
						refresh();
					}
				}
			}
		);
	}
	
	protected SimpleDataGrid<Customer> createTable(){
		return new SimpleDataGrid<Customer>(
			   MaxRecordsPerPage,
			   customerTableHandler = new CustomerTableHandler()
		);
	}
	
	private class SexCellRenderer extends CellRenderer<Customer> {

		@Override
		public void render(SimpleDataModel<Customer> model, ColumnConfig columnConfig, int rowIndex, int colIndex, SafeHtmlBuilder sb) {
			Customer info = model.getObject();
			int sex = info.getSex();
			if(sex == Sex.NotSure){
				sb.append(SimpleLabel.createWarnning("不确定").asSafeHtml());
			}
			else if(sex == Sex.Female){
				sb.append(SimpleLabel.createDanger("女性").asSafeHtml());
			}
			else if(sex == Sex.Male){
				sb.append(SimpleLabel.createSuccess("男性").asSafeHtml());
			}
		}
	}
	
	private class CNameCellRenderer extends CellRenderer<Customer> {

		@Override
		public void render(SimpleDataModel<Customer> model,
				ColumnConfig columnConfig, int rowIndex, int colIndex,
				SafeHtmlBuilder sb) {
			Customer info = model.getObject();
			sb.appendHtmlConstant(
			  "<div style='font-size:13px; font-weight:bold; padding:10px'>"
			  +info.getCName()
			  +"</div>"
			);
		}
		
	}
	
	private final class CustomerTableHandler extends SimpleDataGridHandler<Customer> {
		
		private final static String Name 		  = "Name";
		private final static String CName		  = "CName";
		private final static String Sex			  = "Sex";
		private final static String Email1		  = "Email";
		private final static String Email2		  = "Email2";
		private final static String HasID		  = "HasID";
		private final static String PhoneNumber1  = "PhoneNumber";
		private final static String PhoneNumber2  = "PhoneNumber2";
		private final static String Address1	  = "Address";
		private final static String Address2	  = "Address2";
		private final static String DateCreated   = "DateCreated";
		
		private List<Customer> data;
		
		@Override
		public List<ColumnConfig> createColumns() {
			List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
			configs.add(ColumnConfigs.create(Name, 		   "英文名",    100));
			configs.add(ColumnConfigs.create(CName, 	   "中文名",    100, new CNameCellRenderer()));
			configs.add(ColumnConfigs.create(Sex, 		   "性别",     50,   new SexCellRenderer()));
			configs.add(ColumnConfigs.create(Email1, 	   "电子邮件",  100));
			configs.add(ColumnConfigs.create(PhoneNumber1, "电话号码1", 80));
			configs.add(ColumnConfigs.create(Address1, 	   "地址1",    100));
			configs.add(ColumnConfigs.create(HasID, 	   "身份证",    50, new CheckBoxCellRenderer<Customer>()));
			configs.add(ColumnConfigs.create(DateCreated,  "创建日期",  100, HasAlignment.ALIGN_LEFT, DateFormats.DD_MM_YY));
			return configs;
		}

		@Override
		public void format(int index, SimpleDataModel<Customer> model) {
			Customer customer = model.getObject();
			model.set(Name,  	    customer.getName());
			model.set(CName, 	    customer.getCName());
			model.set(Sex, 		    customer.getSex());
			model.set(HasID, 		false);
			model.set(Email1, 	    customer.getEmail1());
			model.set(Email2, 	    Util.getString(customer.getEmail2()));
			model.set(PhoneNumber1, customer.getPhoneNumber1());
			model.set(PhoneNumber2, Util.getString(customer.getPhoneNumber2()));
			model.set(Address1,     customer.getAddress1());
			model.set(Address2,     Util.getString(customer.getAddress2()));
			model.set(DateCreated,  customer.getDateCreated());
		}
		
		public void setObjects(List<Customer> customerInfos){
			data = customerInfos;
			this.getGrid().setObjects(customerInfos);
		}
		
		@Override
		public List<Customer> getObjects() {
			return data;
		}

		@Override
		public void onObjectClicked(Customer obj) {
			if (obj != null){
				purchaseListBtn.setEnabled(true);
				deleteBtn.setEnabled(true);
				updateBtn.setEnabled(true);
			}
		}

		@Override
		public void onObjectDoubleClicked(Customer obj) {
			onObjectClicked(obj);
		}
		
	}
}
